<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue'
import _axios from "/src/utils/myAxios.js"
import { ElMessage, ElMessageBox } from 'element-plus'

let current = ref(1)
let size = ref(10)
let total = ref(0)

let dialog = ref({
    visible: false,
    title: ''
})

//表单
let form = ref({
    id: undefined,
    roleName: undefined,
    roleKey: undefined,
    roleSort: 1,
    status: 0,
    menuIds: [],
})
let formRule = reactive({
    roleName: [
        { required: true, message: '角色名称不能为空', trigger: 'blur' }
    ],
    roleKey: [
        { required: true, message: '权限字符不能为空', trigger: 'blur' }
    ],
    roleSort: [
        { required: true, message: '显示顺序不能为空', trigger: 'blur' },
    ]
})

let formRef = ref()

let menuExpand = ref(false)
let menuNodeAll = ref(false)
let menuOptions = ref([])
let defaultProps = ref({
    children: 'children',
    label: 'menuName'
})

//重置表单
function resetForm() {
    form.value = {
        id: undefined,
        roleName: undefined,
        roleKey: undefined,
        roleSort: 1,
        status: 0,
        menuIds: undefined
    }
}
//搜索选项
let searchRole = ref({
    roleName: undefined,
    status: undefined
})

//获取的角色列表
let role = ref([])

let menu = ref([])

let roleIds = ref([])

//获取全部角色
async function getRole() {
    let resp = await _axios.post('/api/role/listAllRole', {
        current: current.value,
        size: size.value,
        roleName: searchRole.value.roleName,
        status: searchRole.value.status
    })
    if (resp.data.code === 200) {
        role.value = resp.data.data.rows
        total.value = resp.data.data.total
    } else {
        ElMessage({
            showClose: true,
            message: resp.data.message,
            type: 'error',
            appendTo: "#app",
        })
    }
}

//获取菜单树
async function getMenuTreeselect() {
    let resp = await _axios.get('/api/menu/treeSelect')
    if (resp.data.code === 200) {
        menuOptions.value = resp.data.data
    } else {
        ElMessage({
            showClose: true,
            message: resp.data.message,
            type: 'error',
            appendTo: "#app",
        })
    }
}
onMounted(() => {
    getRole()
})

// 树权限（展开/折叠）
function handleCheckedTreeExpand(value) {
    const treeList = menuOptions.value;
    for (let i = 0; i < treeList.length; i++) {
        menu.value.store.nodesMap[treeList[i].id].expanded = value
    }
}
//树权限（全选/全不选）
function handleCheckedTreeNodeAll(value) {
    menu.value.setCheckedNodes(value ? menuOptions.value : [])
}

//获取选中的菜单
function getMenuAllCheckedKeys() {
    form.value.menuIds = menu.value.getCheckedKeys()
    menu.value.getHalfCheckedKeys().forEach(id => form.value.menuIds.push(id))
}
//打开新建
function handleAdd() {
    resetForm()
    getMenuTreeselect()
    dialog.value.title = "添加角色"
    dialog.value.visible = true
}

//改变角色状态
function changeStatus(a) {
    const text = a.status === '0' ? '启用' : '停用'
    ElMessageBox.confirm(
        '确认要 ' + text + '' + a.roleName + ' 角色吗？',
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(() => {
        return _axios.put('/api/role/updateStatus', {
            id: a.id,
            status: a.status
        })

    })
        .then(() => {
            ElMessage({
                showClose: true,
                message: text + "成功",
                type: 'success',
                appendTo: "#app",
            })
        })
        .catch(() => {
            a.status = a.status === '0' ? '1' : '0'
        })
}

//添加和修改
function submitForm() {
    formRef.value.validate(async valid => {
        if (valid) {
            if (form.value.id === undefined) {
                getMenuAllCheckedKeys()
                let resp = await _axios.post('/api/role/addRole', form.value)
                if (resp.data.code === 200) {
                    dialog.value.visible = false
                    getRole()
                    ElMessage({
                        showClose: true,
                        message: "添加角色成功",
                        type: 'success',
                        appendTo: "#app"
                    })
                } else {
                    ElMessage({
                        showClose: true,
                        message: resp.data.message,
                        type: 'error',
                        appendTo: "#app"
                    })
                }
            } else {
                getMenuAllCheckedKeys()
                let resp = await _axios.put('/api/role/updateRole', form.value)
                if (resp.data.code === 200) {
                    dialog.value.visible = false
                    getRole()
                    ElMessage({
                        showClose: true,
                        message: "修改角色成功",
                        type: 'success',
                        appendTo: "#app"
                    })
                } else {
                    ElMessage({
                        showClose: true,
                        message: resp.data.message,
                        type: 'error',
                        appendTo: "#app"
                    })
                }
            }
        } else {
            ElMessage({
                showClose: true,
                message: '请按规则填写',
                type: 'warning',
                appendTo: "#app"
            })
        }
    })
}

function cancel() {
    dialog.value.visible = false;
}

//打开修改角色
async function getRoleById(id) {
    let resp = await _axios.get(`/api/role/getRoleById/${id}`)
    let res = await _axios.get('/api/menu/treeSelect')
    if (resp.data.code === 200 && res.data.code === 200) {
        form.value = resp.data.data
        dialog.value.title = "修改角色"
        dialog.value.visible = true
        nextTick(() => {
            menuOptions.value = res.data.data
            let menutree = resp.data.data.menuTree
            if (menutree != null) {
                let menuIds = menutree.map(m => m.id)
                menuIds.forEach(v => {
                    nextTick(() => {
                        menu.value.setChecked(v, true, false)
                    })
                })
            }
        })
    }

}

//单个删除
function delRole(id) {
    ElMessageBox.confirm(
        '确认要删除该角色吗？',
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(async () => {
        let resp = await _axios.delete(`/api/role/deleteRole/${id}`)
        return resp
    }).then((resp) => {
        if (resp.data.code === 200) {
            ElMessage({
                showClose: true,
                message: "删除成功",
                type: 'success',
                appendTo: "#app",
            })
            getRole()
        }else{
            ElMessage({
                showClose: true,
                message: resp.data.message,
                type: 'warning',
                appendTo: "#app",
            })
        }
    })
}
function delBatchRole() {
    ElMessageBox.confirm(
        '确认要删除吗？',
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(async () => {
        let resp = await _axios.delete(`/api/role/delBatchRole/${roleIds.value}`)
        return resp
    })
        .then((resp) => {
            if (resp.data.code === 200) {
                ElMessage({
                    showClose: true,
                    message: "删除成功",
                    type: 'success',
                    appendTo: "#app",
                })
                getRole()
            }else{
                ElMessage({
                    showClose: true,
                    message: resp.data.message,
                    type: 'warning',
                    appendTo: "#app",
                })
            }
        })
}

//当选中的角色改变时，重新给roleIds赋值
function changeRoleId(selection) {
    roleIds.value = selection.map(item => item.id)
}

//导出角色数据
function exportRole() {
    ElMessageBox.confirm(
        '确认要导出所有角色数据吗？',
        '系统提示',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
        }
    ).then(async () => {
        let res = await _axios.get('/api/role/export', {
            responseType: 'blob'
        })
        if (!res.data) {
            return
        }
        var blob = new Blob([res.data])
        const contentDisposition = res.headers['content-disposition']
        var fileName = 'test.xlsx'
        if (contentDisposition) {
            fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1], 'UTF-8')
        }
        var url = window.URL.createObjectURL(blob)
        var aLink = document.createElement('a')
        aLink.style.display = 'none'
        aLink.href = url
        aLink.setAttribute('download', fileName)
        document.body.appendChild(aLink)
        aLink.click()
        document.body.removeChild(aLink) // 下载完成移除元素
        window.URL.revokeObjectURL(url) // 释放掉blob对象
        return res
    })
        .then(() => {
            ElMessage({
                showClose: true,
                message: "数据导出成功",
                type: 'success',
                appendTo: "#app",
            })
            getMenu()
        })
}

</script>

<template>
    <div class="backMain">
        <el-form>
            <div class=" backMain-search">
                <el-form-item label="角色名称">
                    <el-input v-model="searchRole.roleName" placeholder="请输入角色名称" />
                </el-form-item>
                <el-form-item label="用户状态">
                    <el-select v-model="searchRole.status" placeholder="请选择用户状态">
                        <el-option label="正常" value=0 />
                        <el-option label="停用" value=1 />
                    </el-select>
                </el-form-item>
                <el-button type="primary" style="margin-left: 15px;" @click="getRole()">搜索</el-button>
            </div>
            <div class="addAndDel">
                <el-button type="primary" plain size="small" @click="handleAdd()">
                    <el-icon>
                        <iEpPlus />
                    </el-icon>&nbsp;
                    新增
                </el-button>
                <el-button type="warning" plain size="small" @click="delBatchRole()">
                    <el-icon>
                        <iEpDelete />
                    </el-icon>&nbsp;
                    删除
                </el-button>
                <el-button type="danger" plain size="small" @click="exportRole()">
                    <el-icon>
                        <iEpDownload />
                    </el-icon>&nbsp;
                    导出
                </el-button>
            </div>
            <div class="user-content">
                <el-table :data="role" style="width: 100%;margin-top: 10px;" @selection-change="changeRoleId"
                    :cell-style="{ backgroundColor: 'var(--el-page-bg-color)' }">
                    <el-table-column type="selection" width="55" />
                    <el-table-column prop="id" label="角色编号" align="center" />
                    <el-table-column prop="roleName" label="角色名称" align="center" />
                    <el-table-column prop="roleKey" label="权限字符" align="center" />
                    <el-table-column prop="roleSort" label="显示顺序" align="center" />
                    <el-table-column prop="status" label="状态" align="center">
                        <template #default="scope">
                            <el-switch v-model="scope.row.status" active-value='0' inactive-value='1'
                                @change="changeStatus(scope.row)" />
                        </template>
                    </el-table-column>
                    <el-table-column prop="createTime" label="创建时间" align="center" />
                    <el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
                        <template #default="scope">
                            <el-button text style="color: #409EFF" @click="getRoleById(scope.row.id)">编辑</el-button>
                            <el-button text style="color: #409EFF" @click="delRole(scope.row.id)">删除</el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </div>
        </el-form>
        <div>
            <el-pagination v-model:current-page="current" v-model:page-size="size" :page-sizes="[10, 20, 30, 40]"
                size="small" layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="getRole"
                @current-change="getRole" />
        </div>
        <!-- 添加和修改 -->
        <el-dialog v-model="dialog.visible" :title="dialog.title" width="600" align-center append-to-body
            style="background-color: #fff;font-weight: 600;">
            <el-form :inline="true" :model="form" :rules="formRule" ref="formRef">
                <el-form-item prop="roleName" label="角色名称" size="large" style="width: 100%;">
                    <el-input v-model="form.roleName" placeholder="请输入角色名称" />
                </el-form-item>
                <div style="display: flex;">
                    <el-form-item prop="roleKey" label="权限字符" size="large">
                        <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
                    </el-form-item>
                    <el-form-item prop="roleSort" label="显示顺序" size="large" v-if="form.id == undefined">
                        <el-input-number v-model="form.roleSort" :min="1" controls-position="right" />
                    </el-form-item>
                </div>
                <div style="display: flex;">
                    <el-form-item label="用户状态">
                        <el-radio-group v-model="form.status">
                            <el-radio :value=0>正常</el-radio>
                            <el-radio :value=1>停用</el-radio>
                        </el-radio-group>
                    </el-form-item>
                </div>
                <el-form-item label="菜单权限" size="large">
                    <div style="width: 100%;">
                        <el-checkbox v-model="menuExpand"
                            @change="handleCheckedTreeExpand(menuExpand)">展开/折叠</el-checkbox>
                        <el-checkbox v-model="menuNodeAll"
                            @change="handleCheckedTreeNodeAll(menuNodeAll)">全选/全不选</el-checkbox>
                    </div>
                    <el-tree ref="menu" class="tree-border" :data="menuOptions" show-checkbox node-key="id"
                        empty-text="加载中，请稍候" :props="defaultProps" />
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="cancel">取消</el-button>
                    <el-button type="primary" @click="submitForm()">
                        确认
                    </el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<style scoped></style>